﻿#region

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Media;
using System.Windows.Forms;
using EditeurSyntaxiqueVocal.Class;
using EditeurSyntaxiqueVocal.Controls;
using EditeurSyntaxiqueVocal.Properties;
using SpeechLib;
using EditeurSyntaxiqueVocal.LesOnglets;

#endregion

namespace EditeurSyntaxiqueVocal.Forms.CommunicationsForm
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="eventArgs"></param>
    public delegate void DelegateEtatVoiceChange(object sender, EventArgs eventArgs);

    /// <summary>
    /// 
    /// </summary>
    public class CommunicationForm : DragForm
    {
        #region - Vars -

        private EtatCommunicationForm _EtatSpeech;
        private string appPath;
        private ToolStripMenuItem awakeToolStripMenuItem;
        private ContextMenuStrip contextMenuStrip1;
        private ToolStripMenuItem disableToolStripMenuItem;
        private ToolStripMenuItem enableToolStripMenuItem;
        private MainForm mf;
        private NotifyIcon notifyIconComunicationFrom;
        public SoundPlayer playerSpeechDisambiguation;
        public SoundPlayer playerSpeechMisrecognition;
        public SoundPlayer playerSpeechOff;
        public SoundPlayer playerSpeechOn;
        public SoundPlayer playerSpeechSleep;
        public SoundPlayer playerSpeechReconitionFin;
        private VistaButton vistaButtonActivDésa;
        private VistaButton vistaButtonAfficheur;
        private ISpeechRecoGrammar VoixStartEndgrammar;
        public SpSharedRecoContext VoixStartEndObjRecoContex;
        private ISpeechGrammarRule VoixStartEndRule;
        public Timer timer = new Timer();

        //Event
        public event DelegateEtatVoiceChange EtatVoiceChange = null;
        public event EventHandler VoiceAllEnd = null;


        #endregion

        #region

        #region - Spetia Form -

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bActivate"></param>
        public new virtual void Show(bool bActivate)
        {
            if (bActivate)
                Show();
            //else
           //     NativeMethods.ShowWindow(Handle, (int) ShowWindowStyles.SW_SHOWNOACTIVATE);
        }

        private void CommunicationForm_Load(object sender, EventArgs e)
        {
            if (mf != null)
            {
                Location = new Point(mf.Location.X + mf.Width/2 + Width/2, mf.Location.Y + 30);
                try
                {
                    MainForm.OngletActive.EditeurTextOnglet.Focus();
                }
                catch (Exception)
                {
                }
            }
            EtatCommunicationForm = EtatCommunicationForm.EnVeille;
        }

        #endregion

        #region -  Designer  -

        private IContainer components;

        /// <summary>
        /// Release resources used by the control.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region -  Component Designer generated code  -

        private void InitializeComponent()
        {
            components = new Container();
            ComponentResourceManager resources = new ComponentResourceManager(typeof (CommunicationForm));
            notifyIconComunicationFrom = new NotifyIcon(components);
            contextMenuStrip1 = new ContextMenuStrip(components);
            enableToolStripMenuItem = new ToolStripMenuItem();
            awakeToolStripMenuItem = new ToolStripMenuItem();
            disableToolStripMenuItem = new ToolStripMenuItem();
            vistaButtonAfficheur = new VistaButton();
            vistaButtonActivDésa = new VistaButton();
            contextMenuStrip1.SuspendLayout();
            SuspendLayout();
            // 
            // notifyIconComunicationFrom
            // 
            notifyIconComunicationFrom.BalloonTipIcon = ToolTipIcon.Info;
            notifyIconComunicationFrom.BalloonTipText = "Editeur Syntaxique Vocal";
            notifyIconComunicationFrom.BalloonTipTitle = "Editeur Syntaxique Vocal";
            notifyIconComunicationFrom.ContextMenuStrip = contextMenuStrip1;
            notifyIconComunicationFrom.Icon = ((Icon) (resources.GetObject("notifyIconComunicationFrom.Icon")));
            notifyIconComunicationFrom.Text = "Editeur Syntaxique Vocal";
            notifyIconComunicationFrom.Visible = true;
            notifyIconComunicationFrom.Click += notifyIconComunicationFrom_Click;
            // 
            // contextMenuStrip1
            // 
            contextMenuStrip1.Items.AddRange(new ToolStripItem[]
                                                 {
                                                     enableToolStripMenuItem,
                                                     awakeToolStripMenuItem,
                                                     disableToolStripMenuItem
                                                 });
            contextMenuStrip1.Name = "contextMenuStrip1";
            contextMenuStrip1.ShowCheckMargin = true;
            contextMenuStrip1.ShowImageMargin = false;
            contextMenuStrip1.Size = new Size(145, 70);
            // 
            // enableToolStripMenuItem
            // 
            enableToolStripMenuItem.Name = "enableToolStripMenuItem";
            enableToolStripMenuItem.Size = new Size(144, 22);
            enableToolStripMenuItem.Text = "Enable Voice";
            enableToolStripMenuItem.Click += enableToolStripMenuItem_Click;
            // 
            // awakeToolStripMenuItem
            // 
            awakeToolStripMenuItem.Name = "awakeToolStripMenuItem";
            awakeToolStripMenuItem.Size = new Size(144, 22);
            awakeToolStripMenuItem.Text = "Awake Voice";
            awakeToolStripMenuItem.Click += awakeToolStripMenuItem_Click;
            // 
            // disableToolStripMenuItem
            // 
            disableToolStripMenuItem.Name = "disableToolStripMenuItem";
            disableToolStripMenuItem.Size = new Size(144, 22);
            disableToolStripMenuItem.Text = "Disable Voice";
            disableToolStripMenuItem.Click += disableToolStripMenuItem_Click;
            // 
            // vistaButtonAfficheur
            // 
            vistaButtonAfficheur.BackColor = Color.Transparent;
            vistaButtonAfficheur.ButtonText = "En Veille";
            vistaButtonAfficheur.CornerRadius = 5;
            vistaButtonAfficheur.Location = new Point(53, 6);
            vistaButtonAfficheur.Name = "vistaButtonAfficheur";
            vistaButtonAfficheur.Size = new Size(242, 43);
            vistaButtonAfficheur.TabIndex = 11;
            vistaButtonAfficheur.TextAlign = ContentAlignment.MiddleLeft;
            vistaButtonAfficheur.MouseMove += CommunicationForm_MouseMove;
            vistaButtonAfficheur.MouseDown += CommunicationForm_MouseDown;
            vistaButtonAfficheur.MouseUp += CommunicationForm_MouseUp;
            // 
            // vistaButtonActivDésa
            // 
            vistaButtonActivDésa.BackColor = Color.Transparent;
            vistaButtonActivDésa.BaseColor = Color.SpringGreen;
            vistaButtonActivDésa.ButtonColor = Color.Blue;
            vistaButtonActivDésa.ButtonText = null;
            vistaButtonActivDésa.ContextMenuStrip = contextMenuStrip1;
            vistaButtonActivDésa.CornerRadius = 18;
            vistaButtonActivDésa.Image = Resources.chat;
            vistaButtonActivDésa.Location = new Point(9, 9);
            vistaButtonActivDésa.Name = "vistaButtonActivDésa";
            vistaButtonActivDésa.Size = new Size(38, 38);
            vistaButtonActivDésa.TabIndex = 0;
            vistaButtonActivDésa.Click += vistaButtonActivDésa_Click;
            // 
            // CommunicationForm
            // 
            AutoScaleDimensions = new SizeF(6F, 13F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(315, 55);
            Controls.Add(vistaButtonAfficheur);
            Controls.Add(vistaButtonActivDésa);
            DoubleBuffered = true;
            FormBorderStyle = FormBorderStyle.None;
            MaximumSize = new Size(315, 55);
            MinimumSize = new Size(315, 55);
            Name = "CommunicationForm";
            ShowIcon = false;
            ShowInTaskbar = false;
            SizeGripStyle = SizeGripStyle.Hide;
            Load += CommunicationForm_Load;
            MouseUp += CommunicationForm_MouseUp;
            Paint += CommunicationForm_Paint;
            MouseDown += CommunicationForm_MouseDown;
            FormClosing += CommunicationForm_FormClosing;
            Resize += CommunicationForm_Resize;
            MouseMove += CommunicationForm_MouseMove;
            LocationChanged += new EventHandler(CommunicationForm_LocationChanged);
            contextMenuStrip1.ResumeLayout(false);
            ResumeLayout(false);
        }

        void CommunicationForm_LocationChanged(object sender, EventArgs e)
        {
            Update();
        }

        #endregion

        #endregion

        #region -  Enums  -

        #region State enum

        /// <summary>
        /// A private enumeration that determines 
        /// the mouse state in relation to the 
        /// current instance of the control.
        /// </summary>
        public enum State
        {
            None,
            Hover,
            Pressed
        } ;

        #endregion

        #region Style enum

        /// <summary>
        /// A public enumeration that determines whether
        /// the button background is painted when the 
        /// mouse is not inside the ClientArea.
        /// </summary>
        public enum Style
        {
            /// <summary>
            /// Draw the button as normal
            /// </summary>
            Default,
            /// <summary>
            /// Only draw the background on mouse over.
            /// </summary>
            Flat
        } ;

        #endregion

        #endregion

        #region -  Properties  -

        #region -  Private Variables  -

        public State mButtonState = State.None;
        public Timer mFadeIn = new Timer();
        public Timer mFadeOut = new Timer();
        private int mGlowAlpha;
        public Timer mTimerAfficheText = new Timer();

        #endregion

        #region -  Text  -

        private Color mForeColor = Color.White;
        private string mText = string.Empty;
        private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter;

        /// <summary>
        /// The text that is displayed on the button.
        /// </summary>
        [Category("Text"),
         Description("The text that is displayed on the button.")]
        public override string Text
        {
            get
            {
                try
                {
                    return vistaButtonAfficheur.ButtonText;
                }
                catch
                {
                    return mText;
                }
            }
            set
            {
                vistaButtonAfficheur.ButtonText = "";
                mText = value;
                mTimerAfficheText.Start();
                base.Text = "";
                Invalidate();
            }
        }

        /// <summary>
        /// The color with which the text is drawn.
        /// </summary>
        [Category("Text"),
         Browsable(true),
         DefaultValue(typeof (Color), "White"),
         Description("The color with which the text is drawn.")]
        public override Color ForeColor
        {
            get { return mForeColor; }
            set
            {
                mForeColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The alignment of the button text
        /// that is displayed on the control.
        /// </summary>
        [Category("Text"),
         DefaultValue(typeof (ContentAlignment), "MiddleCenter"),
         Description("The alignment of the button text " +
                     "that is displayed on the control.")]
        public ContentAlignment TextAlign
        {
            get { return mTextAlign; }
            set
            {
                mTextAlign = value;
                Invalidate();
            }
        }

        #endregion

        #region -  Image  -

        private Image mImage;

        private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft;

        private Size mImageSize = new Size(24, 24);

        /// <summary>
        /// The image displayed on the button that 
        /// is used to help the user identify
        /// it's function if the text is ambiguous.
        /// </summary>
        [Category("Image"),
         DefaultValue(null),
         Description("The image displayed on the button that " +
                     "is used to help the user identify" +
                     "it's function if the text is ambiguous.")]
        public Image Image
        {
            get { return mImage; }
            set
            {
                mImage = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The alignment of the image 
        /// in relation to the button.
        /// </summary>
        [Category("Image"),
         DefaultValue(typeof (ContentAlignment), "MiddleLeft"),
         Description("The alignment of the image " +
                     "in relation to the button.")]
        public ContentAlignment ImageAlign
        {
            get { return mImageAlign; }
            set
            {
                mImageAlign = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The size of the image to be displayed on the
        /// button. This property defaults to 24x24.
        /// </summary>
        [Category("Image"),
         DefaultValue(typeof (Size), "24, 24"),
         Description("The size of the image to be displayed on the" +
                     "button. This property defaults to 24x24.")]
        public Size ImageSize
        {
            get { return mImageSize; }
            set
            {
                mImageSize = value;
                Invalidate();
            }
        }

        #endregion

        #region -  Appearance  -

        private Image mBackImage;
        private Color mBaseColor = Color.Black;
        private Color mButtonColor = Color.Black;
        private Style mButtonStyle = Style.Default;

        private int mCornerRadius = 8;
        private Color mGlowColor = Color.FromArgb(141, 189, 255);

        private Color mHighlightColor = Color.White;

        /// <summary>
        /// Sets whether the button background is drawn 
        /// while the mouse is outside of the client area.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(typeof (Style), "Default"),
         Description("Sets whether the button background is drawn " +
                     "while the mouse is outside of the client area.")]
        public Style ButtonStyle
        {
            get { return mButtonStyle; }
            set
            {
                mButtonStyle = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The radius for the button corners. The 
        /// greater this value is, the more 'smooth' 
        /// the corners are. This property should
        ///  not be greater than half of the 
        ///  controls height.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(8),
         Description("The radius for the button corners. The " +
                     "greater this value is, the more 'smooth' " +
                     "the corners are. This property should " +
                     "not be greater than half of the " +
                     "controls height.")]
        public int CornerRadius
        {
            get { return mCornerRadius; }
            set
            {
                mCornerRadius = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The colour of the highlight on the top of the button.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(typeof (Color), "White"),
         Description("The colour of the highlight on the top of the button.")]
        public Color HighlightColor
        {
            get { return mHighlightColor; }
            set
            {
                mHighlightColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The bottom color of the button that 
        /// will be drawn over the base color.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(typeof (Color), "Black"),
         Description("The bottom color of the button that " +
                     "will be drawn over the base color.")]
        public Color ButtonColor
        {
            get { return mButtonColor; }
            set
            {
                mButtonColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The colour that the button glows when
        /// the mouse is inside the client area.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(typeof (Color), "141,189,255"),
         Description("The colour that the button glows when " +
                     "the mouse is inside the client area.")]
        public Color GlowColor
        {
            get { return mGlowColor; }
            set
            {
                mGlowColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The background image for the button, 
        /// this image is drawn over the base 
        /// color of the button.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(null),
         Description("The background image for the button, " +
                     "this image is drawn over the base " +
                     "color of the button.")]
        public Image BackImage
        {
            get { return mBackImage; }
            set
            {
                mBackImage = value;
                Invalidate();
            }
        }

        /// <summary>
        /// The backing color that the rest of 
        /// the button is drawn. For a glassier 
        /// effect set this property to Transparent.
        /// </summary>
        [Category("Appearance"),
         DefaultValue(typeof (Color), "Black"),
         Description("The backing color that the rest of" +
                     "the button is drawn. For a glassier " +
                     "effect set this property to Transparent.")]
        public Color BaseColor
        {
            get { return mBaseColor; }
            set
            {
                mBaseColor = value;
                Invalidate();
            }
        }

        #endregion

        #endregion

        #region -  Functions  -

        private GraphicsPath RoundRect(RectangleF r, float r1, float r2, float r3, float r4)
        {
            float x = r.X, y = r.Y, w = r.Width, h = r.Height;
            GraphicsPath rr = new GraphicsPath();
            rr.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);
            rr.AddLine(x + r1, y, x + w - r2, y);
            rr.AddBezier(x + w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);
            rr.AddLine(x + w, y + r2, x + w, y + h - r3);
            rr.AddBezier(x + w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);
            rr.AddLine(x + w - r3, y + h, x + r4, y + h);
            rr.AddBezier(x + r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);
            rr.AddLine(x, y + h - r4, x, y + r1);
            return rr;
        }

        #endregion

        #region -  Drawing  -

        /// <summary>
        /// Draws the outer border for the control
        /// using the ButtonColor property.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawOuterStroke(Graphics g)
        {
            if (ButtonStyle == Style.Flat && mButtonState == State.None)
            {
                return;
            }
            Rectangle r = ClientRectangle;
            r.Width -= 1;
            r.Height -= 1;
            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
            {
                using (Pen p = new Pen(ButtonColor))
                {
                    g.DrawPath(p, rr);
                }
            }
        }

        /// <summary>
        /// Draws the inner border for the control
        /// using the HighlightColor property.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawInnerStroke(Graphics g)
        {
            if (ButtonStyle == Style.Flat && mButtonState == State.None)
            {
                return;
            }
            Rectangle r = ClientRectangle;
            r.X++;
            r.Y++;
            r.Width -= 3;
            r.Height -= 3;
            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
            {
                using (Pen p = new Pen(HighlightColor))
                {
                    g.DrawPath(p, rr);
                }
            }
        }

        /// <summary>
        /// Draws the background for the control
        /// using the background image and the 
        /// BaseColor.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawBackground(Graphics g)
        {
            if (ButtonStyle == Style.Flat && mButtonState == State.None)
            {
                return;
            }
            int alpha = (mButtonState == State.Pressed) ? 204 : 127;
            Rectangle r = ClientRectangle;
            r.Width--;
            r.Height--;
            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
            {
                using (SolidBrush sb = new SolidBrush(BaseColor))
                {
                    g.FillPath(sb, rr);
                }
                SetClip(g);
                if (BackImage != null)
                {
                    g.DrawImage(BackImage, new Rectangle((Width/2) - (BackImage.Width/2),
                                                         (Height/2) - (BackImage.Height/2), BackImage.Width,
                                                         BackImage.Height));
                }
                g.ResetClip();
                using (SolidBrush sb = new SolidBrush(Color.FromArgb(alpha, ButtonColor)))
                {
                    g.FillPath(sb, rr);
                }
            }
        }

        /// <summary>
        /// Draws the Highlight over the top of the
        /// control using the HightlightColor.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawHighlight(Graphics g)
        {
            if (ButtonStyle == Style.Flat && mButtonState == State.None)
            {
                return;
            }
            int alpha = (mButtonState == State.Pressed) ? 60 : 150;
            Rectangle rect = new Rectangle(0, 0, Width, Height/2);
            using (GraphicsPath r = RoundRect(rect, CornerRadius, CornerRadius, 0, 0))
            {
                using (LinearGradientBrush lg = new LinearGradientBrush(r.GetBounds(),
                                                                        Color.FromArgb(alpha, HighlightColor),
                                                                        Color.FromArgb(alpha/3, HighlightColor),
                                                                        LinearGradientMode.Vertical))
                {
                    g.FillPath(lg, r);
                }
            }
        }

        /// <summary>
        /// Draws the glow for the button when the
        /// mouse is inside the client area using
        /// the GlowColor property.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawGlow(Graphics g)
        {
            if (mButtonState == State.Pressed)
            {
                return;
            }
            SetClip(g);
            using (GraphicsPath glow = new GraphicsPath())
            {
                glow.AddEllipse(-5, Height/2 - 10, Width + 11, Height + 11);
                using (PathGradientBrush gl = new PathGradientBrush(glow))
                {
                    gl.CenterColor = Color.FromArgb(mGlowAlpha, GlowColor);
                    gl.SurroundColors = new Color[] {Color.FromArgb(0, GlowColor)};
                    g.FillPath(gl, glow);
                }
            }
            g.ResetClip();
        }

        /// <summary>
        /// Draws the text for the button.
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawText(Graphics g)
        {
            StringFormat sf = StringFormatAlignment(TextAlign);
            Rectangle r = new Rectangle(8, 8, Width - 17, Height - 17);
            g.DrawString(Text, Font, new SolidBrush(ForeColor), r, sf);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="textalign"></param>
        /// <returns></returns>
        public static StringFormat StringFormatAlignment(ContentAlignment textalign)
        {
            StringFormat sf = new StringFormat();
            switch (textalign)
            {
                case ContentAlignment.TopLeft:
                case ContentAlignment.TopCenter:
                case ContentAlignment.TopRight:
                    sf.LineAlignment = StringAlignment.Near;
                    break;
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.MiddleRight:
                    sf.LineAlignment = StringAlignment.Center;
                    break;
                case ContentAlignment.BottomLeft:
                case ContentAlignment.BottomCenter:
                case ContentAlignment.BottomRight:
                    sf.LineAlignment = StringAlignment.Far;
                    break;
            }
            switch (textalign)
            {
                case ContentAlignment.TopLeft:
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.BottomLeft:
                    sf.Alignment = StringAlignment.Near;
                    break;
                case ContentAlignment.TopCenter:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.BottomCenter:
                    sf.Alignment = StringAlignment.Center;
                    break;
                case ContentAlignment.TopRight:
                case ContentAlignment.MiddleRight:
                case ContentAlignment.BottomRight:
                    sf.Alignment = StringAlignment.Far;
                    break;
            }
            return sf;
        }

        /// <summary>
        /// Draws the image for the button
        /// </summary>
        /// <param name="g">The graphics object used in the paint event.</param>
        private void DrawImage(Graphics g)
        {
            if (Image == null)
            {
                return;
            }
            Rectangle r = new Rectangle(8, 8, ImageSize.Width, ImageSize.Height);
            switch (ImageAlign)
            {
                case ContentAlignment.TopCenter:
                    r = new Rectangle(Width/2 - ImageSize.Width/2, 8, ImageSize.Width, ImageSize.Height);
                    break;
                case ContentAlignment.TopRight:
                    r = new Rectangle(Width - 8 - ImageSize.Width, 8, ImageSize.Width, ImageSize.Height);
                    break;
                case ContentAlignment.MiddleLeft:
                    r = new Rectangle(8, Height/2 - ImageSize.Height/2, ImageSize.Width, ImageSize.Height);
                    break;
                case ContentAlignment.MiddleCenter:
                    r = new Rectangle(Width/2 - ImageSize.Width/2, Height/2 - ImageSize.Height/2, ImageSize.Width,
                                      ImageSize.Height);
                    break;
                case ContentAlignment.MiddleRight:
                    r = new Rectangle(Width - 8 - ImageSize.Width, Height/2 - ImageSize.Height/2, ImageSize.Width,
                                      ImageSize.Height);
                    break;
                case ContentAlignment.BottomLeft:
                    r = new Rectangle(8, Height - 8 - ImageSize.Height, ImageSize.Width, ImageSize.Height);
                    break;
                case ContentAlignment.BottomCenter:
                    r = new Rectangle(Width/2 - ImageSize.Width/2, Height - 8 - ImageSize.Height, ImageSize.Width,
                                      ImageSize.Height);
                    break;
                case ContentAlignment.BottomRight:
                    r = new Rectangle(Width - 8 - ImageSize.Width, Height - 8 - ImageSize.Height, ImageSize.Width,
                                      ImageSize.Height);
                    break;
            }
            g.DrawImage(Image, r);
        }

        private void SetClip(Graphics g)
        {
            Rectangle r = ClientRectangle;
            r.X++;
            r.Y++;
            r.Width -= 3;
            r.Height -= 3;
            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
            {
                g.SetClip(rr);
            }
        }

        #endregion

        #region -  Private Subs  -

        private void CommunicationForm_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            DrawBackground(e.Graphics);
            DrawHighlight(e.Graphics);
            DrawImage(e.Graphics);
            DrawGlow(e.Graphics);
            DrawOuterStroke(e.Graphics);
            DrawInnerStroke(e.Graphics);
            DrawText(e.Graphics);
        }

        private void CommunicationForm_Resize(object sender, EventArgs e)
        {
            Rectangle r = ClientRectangle;
            r.X -= 1;
            r.Y -= 1;
            r.Width += 2;
            r.Height += 2;
            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
            {
                Region = new Region(rr);
            }
        }

        #region -  Mouse and Keyboard Events  -

        private void mFadeIn_Tick(object sender, EventArgs e)
        {
            if (vistaButtonActivDésa.ButtonStyle == (VistaButton.Style) Style.Flat)
            {
                vistaButtonActivDésa.mGlowAlpha = 0;
            }
            if (vistaButtonActivDésa.mGlowAlpha + 30 >= 255)
            {
                vistaButtonActivDésa.mGlowAlpha = 255;
                vistaButtonActivDésa.mFadeIn.Stop();
                vistaButtonActivDésa.mFadeOut.Start();
            }
            else
            {
                vistaButtonActivDésa.mGlowAlpha += 30;
            }
            vistaButtonActivDésa.Invalidate();
        }

        private void mFadeOut_Tick(object sender, EventArgs e)
        {
            if (vistaButtonActivDésa.ButtonStyle == (VistaButton.Style) Style.Flat)
            {
                vistaButtonActivDésa.mGlowAlpha = 0;
            }
            if (vistaButtonActivDésa.mGlowAlpha - 30 <= 0)
            {
                vistaButtonActivDésa.mGlowAlpha = 0;
                vistaButtonActivDésa.mFadeOut.Stop();
                vistaButtonActivDésa.mFadeIn.Start();
            }
            else
            {
                vistaButtonActivDésa.mGlowAlpha -= 30;
            }
            vistaButtonActivDésa.Invalidate();
        }

        #endregion

        #endregion

        #region - Events Mouse -

        private bool isMoving;
        private Point originalClick;

        private void CommunicationForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (!isMoving)
            {
                isMoving = true;
                originalClick.X = e.X;
                originalClick.Y = e.Y;
            }
        }

        private void CommunicationForm_MouseMove(object sender, MouseEventArgs e)
        {
            if ((MouseButtons.Left & e.Button) == MouseButtons.Left && isMoving)
            {
                int XChange = Location.X +
                              (e.X - originalClick.X);
                int YChange = Location.Y +
                              (e.Y - originalClick.Y);
                Location = new Point(XChange, YChange);

                try
                {
                    mf.Update();
                }
                catch
                {
                }
            }
        }

        private void CommunicationForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMoving)
            {
                isMoving = false;
            }
        }

        #endregion       

        #endregion

        #region - Constrecteur -

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mf"></param>
        public CommunicationForm(MainForm mf)
        {
            //this.Visible = false;
            InitializeComponent();

            appPath = Application.StartupPath + @"\";
            this.mf = mf;
            InitCom();
            timer.Interval = 3000;
            timer.Enabled = true;
            timer.Tick += timer_Tick;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            switch (_EtatSpeech)
            {
                case EtatCommunicationForm.Vide:
                    break;
                case EtatCommunicationForm.EnVeille:
                    Text = "Sleeping";
                    break;
                case EtatCommunicationForm.Ecoute:
                case EtatCommunicationForm.QuAvezVousDit:
                case EtatCommunicationForm.ExistePas:
                    Text = "Listening"; // "Ecoute";
                    break;
                case EtatCommunicationForm.Désactivé:
                    Text = "Off";
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            //
            timer.Stop();
        }

        /// <summary>
        /// 
        /// </summary>
        public CommunicationForm()
        {
            // this.Visible = false;
            InitializeComponent();
            appPath = Application.StartupPath + @"\";
            InitCom();
        }

        #endregion

        public Onglet OngletActive
        {
            get
            {
                return MainForm.OngletActive;
            }          
        }

        private VoixMainForm _voixMainForm;
        /// <isnew>08/06/2009 19:10:12</isnew>
        /// <permission cref="System.Data.Odbc.OdbcPermission" caption="[New Item]"></permission>
        public VoixMainForm VoixMainForm
        {
            get
            {
                return _voixMainForm;
            }
        }

        /// <summary>
        /// Présente l'état de la reconnaisance vocale.
        /// </summary>
        public EtatCommunicationForm EtatCommunicationForm
        {
            get { return _EtatSpeech; }
            set
            {
                //if (_EtatSpeech != value)
                timer.Stop();
                timer.Start();
                mFadeOut.Stop();
                switch (value)
                {
                    case EtatCommunicationForm.EnVeille:
                        playerSpeechSleep.Play();
                        Text = "Sleeping"; // "En Veille";
                        mFadeIn.Stop();
                        vistaButtonActivDésa.BaseColor = Color.Blue;
                        vistaButtonActivDésa.ButtonColor = Color.SpringGreen;
                        enableToolStripMenuItem.Checked = false;
                        awakeToolStripMenuItem.Checked = true;
                        disableToolStripMenuItem.Checked = false;
                        break;

                    case EtatCommunicationForm.Ecoute:
                        playerSpeechOn.Play();
                        Text = "Listening"; // "Ecoute";
                        mFadeIn.Start();
                        vistaButtonActivDésa.BaseColor = Color.Blue;
                        vistaButtonActivDésa.ButtonColor = Color.Blue;
                        enableToolStripMenuItem.Checked = true;
                        awakeToolStripMenuItem.Checked = false;
                        disableToolStripMenuItem.Checked = false;
                        break;

                    case EtatCommunicationForm.QuAvezVousDit:
                        playerSpeechMisrecognition.Play();
                        Text = "What was that?"; //"Qu'avez-vous dit ?";
                        mFadeIn.Start();
                        vistaButtonActivDésa.BaseColor = Color.Yellow;
                        vistaButtonActivDésa.ButtonColor = Color.LightSalmon;
                        enableToolStripMenuItem.Checked = true;
                        awakeToolStripMenuItem.Checked = false;
                        disableToolStripMenuItem.Checked = false;
                        break;

                    case EtatCommunicationForm.ExistePas:
                        playerSpeechDisambiguation.Play();
                        Text = "This Order is not currently available";
                        //"Cette Commande n'est pas disponible actuellement";
                        mFadeIn.Start();
                        vistaButtonActivDésa.BaseColor = Color.Red;
                        vistaButtonActivDésa.ButtonColor = Color.Red;
                        enableToolStripMenuItem.Checked = true;
                        awakeToolStripMenuItem.Checked = false;
                        disableToolStripMenuItem.Checked = false;
                        break;

                    case EtatCommunicationForm.Désactivé:
                        playerSpeechOff.Play();
                        Text = "The recognition is Disable"; // "La reconnaissance est désactivé";
                        mFadeIn.Stop();
                        vistaButtonActivDésa.BaseColor = SystemColors.ControlLight;
                        vistaButtonActivDésa.ButtonColor = Color.OliveDrab;
                        enableToolStripMenuItem.Checked = false;
                        awakeToolStripMenuItem.Checked = false;
                        disableToolStripMenuItem.Checked = true;
                        break;

                    default:
                        enableToolStripMenuItem.Checked = false;
                        awakeToolStripMenuItem.Checked = false;
                        disableToolStripMenuItem.Checked = false;
                        break;
                }
                _EtatSpeech = value;
                if (EtatVoiceChange != null)
                    EtatVoiceChange(EtatCommunicationForm, null);                
            }
        }

        private void InitialVoiceStartEndObjRecoContext()
        {
            VoixStartEndObjRecoContex = new SpSharedRecoContext();

            VoixStartEndObjRecoContex.Recognition +=
                VoixStartEndObjRecoContext_Recognition;

            VoixStartEndObjRecoContex.Hypothesis +=
                VoixStartEndObjRecoContext_Hypothesis;

            VoixStartEndObjRecoContex.FalseRecognition +=
                VoixStartEndObjRecoContext_FalseRecognition;

            VoixStartEndObjRecoContex.AudioLevel += VoixStartEndObjRecoContex_AudioLevel;
        }

        private void VoixStartEndObjRecoContex_AudioLevel(int StreamNumber, object StreamPosition, int AudioLevel)
        {
            // progressBar1.Value = AudioLevel;
        }

        private void InitVoiceStartEndGrammair()
        {
            try
            {
                VoixStartEndgrammar = VoixStartEndObjRecoContex.CreateGrammar(0);
                VoixStartEndgrammar.CmdLoadFromFile(appPath + @"Grammar 409\GrammaireCf.xml",
                                                    SpeechLoadOption.SLODynamic);
                VoixStartEndgrammar.CmdSetRuleIdState(0, SpeechRuleState.SGDSActive);
            }
            catch (Exception excep)
            {
                //VoixStartEndgrammar.SetDictationState(SpeechLib.SPRULESTATE.SPRS_SPRS_ACTIVE);
                //VoixStartEndgrammar.SetGrammarState(SPGRAMMARSTATE.SPGS_SPGS_ENABLED);
                MessageBox.Show(excep.Message);
                //Application.ExitThread();
            }
        }

        private void DisableVoiceStartEndGrammair()
        {
            try
            {
            }
            catch (Exception excep)
            {
                MessageBox.Show(excep.Message);
            }
        }

        private void VoixStartEndObjRecoContext_Recognition(int StreamNumber, object StreamPosition,
                                                            SpeechRecognitionType RecognitionType,
                                                            ISpeechRecoResult Result)
        {
            string StringRecognition = Result.PhraseInfo.GetText(0, -1, true);

            switch (EtatCommunicationForm)
            {
                case EtatCommunicationForm.Désactivé:
                    break;

                case EtatCommunicationForm.Ecoute:
                case EtatCommunicationForm.ExistePas:
                case EtatCommunicationForm.QuAvezVousDit:
                    switch (Result.PhraseInfo.Rule.Name)
                    {
                        case "voice_sleep":
                            EtatCommunicationForm = EtatCommunicationForm.EnVeille;
                            break;

                        case "voice_end":
                            EtatCommunicationForm = EtatCommunicationForm.Désactivé;
                            break;
                    }
                    break;

                case EtatCommunicationForm.EnVeille:
                    switch (Result.PhraseInfo.Rule.Name)
                    {
                        case "voice_end":
                            EtatCommunicationForm = EtatCommunicationForm.Désactivé;
                            break;

                        case "voice_start":
                            EtatCommunicationForm = EtatCommunicationForm.Ecoute;
                            break;

                        default:
                            Text = "Try saying: \"start listening\"";
                            playerSpeechMisrecognition.Play();
                            break;
                    }
                    break;

                default:
                    break;
            }
        }

        private void VoixStartEndObjRecoContext_FalseRecognition(int StreamNumber, object StreamPosition,
                                                                 ISpeechRecoResult Result)
        {
            string StringRecognition = Result.PhraseInfo.GetText(0, -1, true);

            if (EtatCommunicationForm != EtatCommunicationForm.EnVeille) return;
            Text = "Try saying: \"start listening\"";
            timer.Stop();
            timer.Start();
            playerSpeechMisrecognition.Play();
        }

        private void VoixStartEndObjRecoContext_Hypothesis(int StreamNumber, object StreamPosition,
                                                           ISpeechRecoResult Result)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        public void vistaButtonActivDésa_Click(object sender, EventArgs e)
        {
            //if (MouseButtons.Left == ((MouseEventArgs) e).Button)
            switch (EtatCommunicationForm)
            {
                case EtatCommunicationForm.EnVeille:
                case EtatCommunicationForm.Désactivé:
                case EtatCommunicationForm.Vide:
                    EtatCommunicationForm = EtatCommunicationForm.Ecoute;
                    break;

                case EtatCommunicationForm.Ecoute:
                case EtatCommunicationForm.ExistePas:
                case EtatCommunicationForm.QuAvezVousDit:
                    EtatCommunicationForm = EtatCommunicationForm.EnVeille;
                    break;

                default:
                    break;
            }
        }

        private void CommunicationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            VoixStartEndObjRecoContex = null;
            notifyIconComunicationFrom.Visible = false;
        }

        private void enableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EtatCommunicationForm = EtatCommunicationForm.Ecoute;
        }

        private void awakeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EtatCommunicationForm = EtatCommunicationForm.EnVeille;
        }

        private void disableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EtatCommunicationForm = EtatCommunicationForm.Désactivé;
        }

        private void notifyIconComunicationFrom_Click(object sender, EventArgs e)
        {
            if (((MouseEventArgs) e).Button == MouseButtons.Left)
            {
            }
        }

        #region - InitComp -

        private void InitCom()
        {
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Selectable, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.UserPaint, true);
            Font = new Font("Tahoma", 9F, FontStyle.Regular,
                            GraphicsUnit.Point, ((0)));
            ButtonColor = SystemColors.GradientActiveCaption;
            BaseColor = Color.Transparent;
            BackColor = Color.Transparent;
            CornerRadius = 31;

            vistaButtonAfficheur.KeyDown -=
                vistaButtonAfficheur.VistaButton_KeyDown;
            vistaButtonAfficheur.MouseEnter -=
                vistaButtonAfficheur.VistaButton_MouseEnter;
            vistaButtonAfficheur.MouseLeave -=
                vistaButtonAfficheur.VistaButton_MouseLeave;
            vistaButtonAfficheur.MouseUp -= vistaButtonAfficheur.VistaButton_MouseUp;
            vistaButtonAfficheur.MouseDown -=
                vistaButtonAfficheur.VistaButton_MouseDown;

            vistaButtonAfficheur.mButtonState = (VistaButton.State) State.Hover;
            vistaButtonAfficheur.mFadeIn.Start();

            playerSpeechOn = new SoundPlayer(Resources.Speech_On);
            playerSpeechOn.LoadAsync();
            playerSpeechOff = new SoundPlayer(Resources.Speech_Off);
            playerSpeechOff.LoadAsync();
            playerSpeechSleep = new SoundPlayer(Resources.Speech_Sleep);
            playerSpeechSleep.LoadAsync();
            playerSpeechReconitionFin = new SoundPlayer(Resources.Speech_Reconition_Fin);
            playerSpeechReconitionFin.LoadAsync();
            playerSpeechMisrecognition = new SoundPlayer(Resources.Speech_Disambiguation);
            playerSpeechMisrecognition.LoadAsync();
            playerSpeechDisambiguation = new SoundPlayer(Resources.Speech_Disambiguation);
            playerSpeechDisambiguation.LoadAsync();

            mFadeIn.Tick += mFadeIn_Tick;
            mFadeOut.Tick += mFadeOut_Tick;
            mTimerAfficheText.Interval = 40;
            mTimerAfficheText.Tick += mTimerAfficheText_Tick;

            mFadeIn.Enabled = mFadeOut.Enabled = false;
            mFadeIn.Stop();
            mFadeOut.Stop();

            InitialVoiceStartEndObjRecoContext();
            InitVoiceStartEndGrammair();
        }

        private void mTimerAfficheText_Tick(object sender, EventArgs e)
        {
            mTimerAfficheText.Stop();
            vistaButtonAfficheur.ButtonText = mText;
        }

        

        #endregion

    }
}